﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace VBOX
{
    class tools
    {
        public static void Byte2Ascii(byte[] des, byte[] src, UInt16 cnt)
        {
            byte high;
            byte low;
            UInt16 i = cnt;
            for (i = 0; i < cnt; i++)
            {
                high = (byte)(src[i] >> 4);
                low = (byte)(src[i] & 0xf);
                if (high > 9)
                    high = (byte)(high + 'A' - 0xA);
                else
                    high = (byte)(high + '0');
                des[i * 2] = high;

                if (low > 9)
                    low = (byte)(low + 'A' - 0xA);
                else
                    low = (byte)(low + '0');
                des[i * 2 + 1] = low;
            }
        }

        public static UInt32 Ascii2Byte(byte[] des, byte[] src, UInt16 cnt)
        {
            UInt32 i = 0;
            UInt32 j = 0;
            byte highData;
            byte lowData;
            while (i < cnt)
            {
                if (src[i] == ' ')
                {
                    i++;
                    continue;
                }
                if (i >= src.Length)
                {
                    //MessageBox.Show("数据长度错误");
                    return 0;
                }
                if ((src[i] == 0x0D) && (src[i + 1] == 0x0A))
                {
                    return j;
                }
                if (src[i] <= '9' && src[i] >= '0')
                    highData = (byte)(src[i] - '0');
                else
                {
                    if ((src[i] >= 'A') && (src[i] <= 'Z'))
                    {
                        highData = (byte)(src[i] - 'A' + 0xa);
                    }
                    else if ((src[i] >= 'a') && (src[i] <= 'z'))
                    {
                        highData = (byte)(src[i] - 'a' + 0xa);
                    }
                    else
                    {
                        //MessageBox.Show ("输入的数据无法识别");
                        return 0;
                    }
                }
                i++;
                if (i >= src.Length)
                {
                    //MessageBox.Show("数据长度错误");
                    return 0;
                }
                    
                if (src[i] <= '9' && src[i] >= '0')
                    lowData = (byte)(src[i] - '0');
                else
                {
                    if ((src[i] >= 'A') && (src[i] <= 'Z'))
                    {
                        lowData = (byte)(src[i] - 'A' + 0xa);
                    }
                    else if ((src[i] >= 'a') && (src[i] <= 'z'))
                    {
                        lowData = (byte)(src[i] - 'a' + 0xa);
                    }
                    else
                    {
                        //MessageBox.Show ("数据长度错误");
                        return 0;
                    }
                }

                des[j] = (byte)(lowData + (highData << 4));
                j++;
                i++;
            }
            return j;
        }

        /******************************************************************************** 
        * 函数名称 ：CRC16Caculate 
        * 函数功能 ：计算CRC16的校验和 半字计算法 
        * 参    数 ：AP:要计算的数据指针  LEN：数据长度  CRC16_Type：标准 0x1432 
        * 返 回 值 ：校验结果 
        * 注    意 ： 
        ********************************************************************************/ 
        static UInt16[] CRCTable ={0x0000,0x1021,0x2042,0x3063,0x4084,0x50A5,0x60C6,0x70E7, 
                                        0x8108,0x9129,0xA14A,0xB16B,0xC18C,0xD1AD,0xE1CE,0xF1EF};
        public static UInt16 CRC16Caculate(byte[] AP, UInt16 LEN) 
        { 
            const UInt16 CRC16_Type = 0x1432;
            UInt16  CRC16; 
            UInt16  i; 
            byte  CRC_H4; 
             
            CRC16 = 0xFFFF - CRC16_Type; 
            for (i = 0; i <LEN; i++) 
            { 
                CRC_H4 = (byte)(CRC16 >> 12);                                                                                                                                                                             
                CRC16 = (UInt16)(CRC16 << 4); 
                CRC16 = (UInt16)(CRC16 ^ CRCTable[CRC_H4 ^ (AP[i] >> 4)]); 
                CRC_H4 = (byte)(CRC16 >> 12); 
                CRC16 = (UInt16)(CRC16 << 4); 
                CRC16 = (UInt16)(CRC16 ^ CRCTable[CRC_H4 ^ (AP[i] & 0x0F)]); 
            } 
            return CRC16; 
        }

        public static UInt32 get_data_uint32(byte[] p, ref int pos)
        {
            UInt32 value = 0;
            value = (UInt32)((p[pos] << 24) | (p[pos + 1] << 16) | (p[pos + 2] << 8) | p[pos + 3]);
            pos += 4;
            return value;
        }
        public static UInt16 get_data_uint16(byte[] p, ref int pos)
        {
            UInt16 value = 0;
            value = (UInt16)((p[pos] << 8) | p[pos + 1]);
            pos += 2;
            return value;
        }
        public static byte get_data_uint8(byte[] p, ref int pos)
        {
            byte value = 0;
            value = p[pos];
            pos++;
            return value;
        }

        //base64编码
        public static string EncodeBase64(byte[] bytes, int len)
        {
            byte[] newBytes = new byte[len];

            for(int i = 0; i < len; i++)
            {
                newBytes[i] = bytes[i];
            }

            String strBase64 = Convert.ToBase64String(newBytes);

            return strBase64;
        }

        //base64解码
        public static byte[] DecodeBase64(string base64_code)
        {
            byte[] Bytes = Convert.FromBase64String(base64_code);
            return Bytes;
        }
    }
}
